﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using PloobsEngine.SceneControl;
using PloobsEngine.Cameras;
using PloobsEngine.Light;
using PloobsEngine.Modelo;

namespace PloobsEngine.Material
{
    public class XnaMaterial : IMaterial
    {
        #region IMaterial Members

        private EngineStuff engine;

        public XnaMaterial(EngineStuff engine)
        {
            this.engine = engine;
            effect = new BasicEffect(engine.Game.GraphicsDevice, null);
        }

        private BasicEffect effect;
                
        public void Drawn(Microsoft.Xna.Framework.GameTime gt, IObject obj, ICamera cam, IList<ILight> lights,IRenderHelper render)
        {            
        }

        public void Update(Microsoft.Xna.Framework.GameTime gametime, IObject obj, IList<ILight> lights)
        {
            
        }

        public IShader Shadder
        {
            get
            {
                return null;
            }
            set
            {                
            }
        }

 
        #endregion

        #region IMaterial Members

        public void Serialize(System.Xml.XmlTextWriter textWriter)
        {            
        }
                
        #endregion

        #region IMaterial Members


        public void DeSerialize(System.Xml.XmlNode node, EngineStuff engine, IModelo model)
        {         
        }

        #endregion

        #region IMaterial Members


        public MaterialType MaterialType
        {
            get
            {
                return MaterialType.FORWARD;
                     
            }
            set
            {
                throw new Exception("Only Forward");
            }
        }

        #endregion

        #region IMaterial Members


        public void PreDrawnPhase(IWorld mundo, GameTime gt, IObject obj, ICamera cam, IList<ILight> lights, IRenderHelper render)
        {
            
        }

        #endregion

        #region IMaterial Members


        public bool AffectedByShadow
        {
            get;
            set;
        }

        #endregion

        #region IMaterial Members


        public void PosDrawnPhase(GameTime gt, IObject obj, ICamera cam, IList<ILight> lights, IRenderHelper render)
        {
            engine.Game.GraphicsDevice.RenderState.DepthBufferEnable = true;
            engine.Game.GraphicsDevice.RenderState.DepthBufferWriteEnable = true;

            IModelo modelo = obj.Modelo;
            Matrix[] boneTransforms = modelo.getBonesTransformation();

            Matrix wld = obj.getWorldMatrix();
            for (int i = 0; i < modelo.MeshNumber; i++)
            {
                BatchInformation[] bi = modelo.GetBatchInformation(i);
                Matrix w1 = Matrix.Multiply(wld, boneTransforms[modelo.GetParentBoneIndex(i)]);
                effect.World = w1;
                effect.Projection = cam.Projection;
                effect.View = cam.View;
                effect.EnableDefaultLighting();

                for (int j = 0; j < bi.Count(); j++)
                {
                    effect.Begin();
                    EngineStuff.GraphicsDevice.VertexDeclaration = bi[j].VertexDeclaration;
                    EngineStuff.GraphicsDevice.Vertices[0].SetSource(modelo.GetVertexBuffer(i), bi[j].StreamOffset, bi[j].VertexStride);
                    EngineStuff.GraphicsDevice.Indices = modelo.GetIndexBuffer(i);

                    effect.CurrentTechnique.Passes[0].Begin();
                    EngineStuff.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, bi[j].BaseVertex, 0, bi[j].NumVertices, bi[j].StartIndex, bi[j].PrimitiveCount);
                    effect.CurrentTechnique.Passes[0].End();
                    effect.End();
                }
            }

            
        }

        #endregion


        #region IMaterial Members


        public IDepthExtractor DepthExtractor
        {
            get { return null; }
        }

        #endregion
    }
}
